<template>
  <div>
    <el-card class="box-card" style="margin-bottom: 10px;">
      <!-- 表单部分 -->
      <el-form :model="form" :inline="true" class="demo-ruleForm" :rules="rules" ref="form" label-width="100px">
        <el-form-item label="算法版本" prop="version">
          <el-tooltip effect="dark" content="选择要攻击的算法版本" placement="top">
            <el-select v-model="form.version" placeholder="请选择算法版本">
              <el-option label="KYBER512" value="512"></el-option>
              <el-option label="KYBER768" value="768"></el-option>
              <el-option label="KYBER1024" value="1024"></el-option>
            </el-select>
          </el-tooltip>
        </el-form-item>
        <el-form-item label="密文过滤" prop="filter">
          <el-tooltip effect="dark" content="是否使用密文过滤技术提高不等式信息量" placement="top">
            <el-select v-model="form.filter" placeholder="请选择不等式类型">
              <el-option label="过滤" value="true"></el-option>
              <el-option label="不过滤" value="false"></el-option>
            </el-select>
          </el-tooltip>
        </el-form-item>
        <el-form-item label="种子" prop="seed">
          <el-tooltip effect="dark" content="生成不等式参数使用的种子" placement="top">
            <el-input v-model.number="form.seed" placeholder="请输入随机数种子"></el-input>
          </el-tooltip>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :loading="submitLoading" @click="submitForm('form')">提交</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-dialog :title="dialogTitle" :visible="dialogVisible" width="30%" center :before-close="handleClose">
      <el-progress :percentage="progress" />
      <span slot="footer" class="dialog-footer">
        <el-button type="danger" :disabled="progress >= 100" @click="handleClose">取消生成</el-button>
        <el-button type="primary" :loading="okLoading" @click="dialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>

    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span style="margin-right: 10px;">选择要查看的不等式组</span>
        <el-select v-model="selectedIneq" placeholder="请选择不等式">
          <el-option v-for="ineq in ineqName" :key="ineq" :label="ineq" :value="ineq" />
        </el-select>
      </div>

      <el-empty v-if="selectedIneq == ''" description="暂无不等式，请先生成吧！"></el-empty>

      <el-descriptions v-else :title="selectedIneq" :column="2" direction="vertical"
        :labelStyle="{ 'font-weight': 'bold', 'font-size': '16px' }">
        <el-descriptions-item label="密钥信息">
          <span style="margin: 0px 20px;">密钥(e,s)长度为{{ version + 256 }}</span><br>
          <span style="margin: 0px 20px;">其中e有256个分量，s有{{ version }}个分量</span>
        </el-descriptions-item>
        <el-descriptions-item label="查看密钥">
          <el-row style="margin-bottom: 10px;">
            <el-col :span="8">
              <span style="margin-left: 20px;">选择要查看的密钥</span><br>
            </el-col>
          </el-row>
          <el-row style="margin-bottom: 10px;">
            <el-col :span="5">
              <span style="width:100px;margin-left: 20px;">密钥e系数索引</span>
            </el-col>
            <el-col :span="6">
              <el-input-number v-model="selectedKeyEIndex" :min="0" :max="256 - 1" size="small"
                style="margin-left: 20px;">
              </el-input-number>
              <br>
            </el-col>
          </el-row>
          <el-row style="margin-bottom: 10px;">
            <el-col :span="5">
              <span style="width:100px;margin-left: 20px;">密钥s系数索引</span>
            </el-col>
            <el-col :span="6">
              <el-input-number v-model="selectedKeySIndex" :min="0" :max="version - 1" size="small"
                style="margin-left: 20px;">
              </el-input-number>
              <br>
            </el-col>
            <el-button type="primary" @click="displayKeyTable" style="margin-left: 20px; margin-top: -5px;">显示密钥</el-button>
          </el-row>
        </el-descriptions-item>
        <el-descriptions-item label="不等式信息">
          <span style="margin-left: 20px;">共生成了{{ inequCount }}个不等式</span><br>
          <span style="margin-left: 20px;">每个不等式具有{{ 256 + version }}个系数，形如</span><br>
          <img src="\src\assets\inequ.png" style="width: 200px; height: auto; margin-left: 20px;" />
        </el-descriptions-item>
        <el-descriptions-item label="查看不等式">
          <el-row style="margin-bottom: 10px;">
            <el-col :span="8">
              <span style="margin-left: 20px;">选择要查看的不等式</span><br>
            </el-col>
          </el-row>
          <el-row style="margin-bottom: 10px;">
            <el-col :span="5">
              <span style="width:100px; margin-left: 20px;">不等式索引</span>
            </el-col>
            <el-col :span="6">
              <el-input-number v-model="selectedInequIndex" :min="1" :max="inequCount" size="small"
                style="margin-left: 20px;">
              </el-input-number><br>
            </el-col>
          </el-row>
          <el-row style="margin-bottom: 10px;">
            <el-col :span="5">
              <span style="width:100px;margin-left: 20px;">系数索引</span>
            </el-col>
            <el-col :span="6">
              <el-input-number v-model="selectedCoeffIndex" :min="0" :max="256 + version - 1" size="small"
                style="margin-left: 20px;">

              </el-input-number><br>
            </el-col>
            <!-- 按钮，用于触发显示表格 -->
            <el-button type="primary" @click="displayCoeffTable" style="margin-left: 20px; margin-top: -5px;">显示不等式</el-button>
          </el-row>
        </el-descriptions-item>
      </el-descriptions>

      <el-drawer :visible.sync="drawKeyVisible" direction="rtl" size="52%" :with-header="false" title="密钥抽屉">
        <!-- 表格用于显示被过滤的列 -->
        <span style="margin: 50px 0 10px 10px;font-weight: bold; font-size: 16px;display: block;">
          密钥e[{{ selectedKeyEIndex }}]及其附近分量
        </span>
        <el-table :data="filteredKeyETableData" ref="keyETable" style="width: 750px; margin: 10px;"
          :cell-style="{ textAlign: 'center' }" :header-cell-style="{ background: '#eef1f6', textAlign: 'center' }">
          <el-table-column v-for="(col, index) of keyTableEColumns" :key="index" :label="col.label" :prop="col.prop"
            :width="tableColumnWidth" />
        </el-table>
        <span style="margin: 30px 0 10px 10px;font-weight: bold; font-size: 16px; display: block;">
          密钥s[{{ selectedKeySIndex }}]及其附近分量
        </span>
        <el-table :data="filteredKeySTableData" ref="keySTable" style="width: 750px; margin: 10px;"
          :cell-style="{ textAlign: 'center' }" :header-cell-style="{ background: '#eef1f6', textAlign: 'center' }">
          <el-table-column v-for="(col, index) of keyTableSColumns" :key="index" :label="col.label" :prop="col.prop"
            :width="tableColumnWidth" />
        </el-table>
      </el-drawer>

      <el-drawer :visible.sync="drawCoeffVisible" direction="rtl" size="50%" :with-header="false" title="不等式抽屉">
        <!-- 表格用于显示被过滤的列 -->
        <span style="margin: 50px 0 10px 10px;font-weight: bold; font-size: 16px;display: block;">
          第{{ selectedInequIndex }}个不等式的上下界及其系数A[{{ selectedCoeffIndex }}]附近系数
        </span>
        <el-table :data="filteredCoeffTableData" ref="coeffTable" style="width: 720px; margin: 10px;"
          v-loading="coeffTableLoading" :cell-style="{ textAlign: 'center' }"
          :header-cell-style="{ background: '#eef1f6', textAlign: 'center' }" stripe>
          <el-table-column label="序号" prop="No" width="65" fixed />
          <el-table-column label="下界" prop="lowerbound" width="60" fixed />
          <el-table-column v-for="(col, index) of coeffTableColumns" :key="index" :label="col.label" :prop="col.prop"
            width=80 />
          <el-table-column label="上界" prop="upperbound" width="60" fixed="right" />
        </el-table>
      </el-drawer>
    </el-card>
  </div>
</template>

<script>
  import axios from 'axios';
  export default {
    data() {
      var validateSeed = (rule, value, callback) => {
        if (!/^\d+$/.test(value)) {
          callback(new Error('种子应为正整数'));
        } else {
          callback();
        }
      };
      return {
        form: {
          version: '',
          filter: '',
          seed: '',
        },
        rules: {
          version: [
            { required: true, message: '请选择算法版本', trigger: 'change' },
          ],
          filter: [
            { required: true, message: '请选择是否过滤密文', trigger: 'change' }
          ],
          seed: [
            { required: true, message: '请输入随机数种子', trigger: 'blur' },
            { validator: validateSeed, trigger: 'change' }
          ]
        },
        coeffTableLoading: true,
        version: 512,
        filter: true,
        submitLoading: false, // 控制提交按钮的加载状态
        dialogVisible: false,
        dialogTitle: '不等式生成中',
        progress: 0,
        okLoading: true,
        selectedIneq: '',
        ineqName: [],
        selectedKeyEIndex: 0,
        selectedKeySIndex: 0,
        selectedCoeffIndex: 0,
        selectedInequIndex: 1,
        inequCount: 1000,
        drawKeyVisible: false,
        drawCoeffVisible: false,
        filteredKeyETableData: [],
        filteredKeySTableData: [],
        keyTableEColumns: [],
        keyTableSColumns: [],
        filteredCoeffTableData: [],
        coeffTableColumns: [],
        keyFileContent: [],
        coeffFileContent: [],
        lvuFileContent: [],
        tableColumnWidth: 75,
      };
    },
    mounted() {
      this.ineqName = sessionStorage.getItem('ineqName') ? JSON.parse(sessionStorage.getItem('ineqName')) : [];
      // this.ineqName = ['cutfilter_Kyber768Simplified_seed7175']
      if (this.ineqName.length > 0) {
        this.selectedIneq = this.ineqName[0];
        const match = this.selectedIneq.match(/\d+/);
        this.version = parseInt(match[0]);
        if (this.selectedIneq[0] == 'c') {
          this.filter = true;
          this.inequCount = 50 * 256;
        } else if (this.selectedIneq[0] == 'u') {
          this.filter = false;
          this.inequCount = 80 * 256;
        }
        this.fetchKeyData();
      }
    },
    watch: {
      selectedIneq: {
        handler(newVal, oldVal) {
          if (newVal) {
            const match = newVal.match(/\d+/);
            this.version = parseInt(match[0]);
            if (newVal[0] == 'c') {
              this.filter = true;
              this.inequCount = 50 * 256;
            } else if (newVal[0] == 'u') {
              this.filter = false;
              this.inequCount = 80 * 256;
            }
            this.fetchKeyData();

          }
        },
        immediate: true // 确保初始时也执行
      },
    },
    methods: {
      submitForm(formName) {
        this.okLoading = true;
        this.progress = 0; // 重置进度条
        this.dialogTitle = '不等式生成中';
        this.$refs[formName].validate((valid) => {
          if (valid) {
            axios.post('http://127.0.0.1:8000/1/genmequ', this.form, {
              headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
              }
            }).then(response => {
              // 请求成功，处理响应数据
              // 根据需要处理response.data，比如更新状态、显示消息等
              this.submitLoading = true;
              // 显示对话框
              this.dialogVisible = true;
              const progressCount = this.form.filter == "true" ? 50 : 80

              // 使用 EventSource 更新进度条
              const eventSource = new EventSource('http://127.0.0.1:8000/1/genmequ_SSE');
              eventSource.onmessage = (event) => {
                const data = event.data.split(' ');
                if (data[0] === 'error') {
                  this.submitLoading = false;
                  this.dialogTitle = '生成过程中出现错误';
                  eventSource.close();
                  this.okLoading = false;
                } else if (data[1] == 'int') {
                  this.progress = Math.floor(100 * Number(data[0]) / progressCount)
                  if (this.progress >= 100) {

                    // 完成提交
                    eventSource.close(); // 关闭 EventSource
                    this.submitLoading = false;
                    this.dialogTitle = '不等式生成完毕';
                    this.okLoading = false;

                    let currentIneqName = '';
                    if (this.form.filter == 'true') {
                      currentIneqName = 'cutfilter_Kyber';
                    } else {
                      currentIneqName = 'unfilter_Kyber';
                    }
                    currentIneqName = currentIneqName + this.form.version + 'Simplified_seed' + this.form.seed;
                    if (!this.ineqName.includes(currentIneqName)) {
                      this.ineqName.push(currentIneqName);
                      sessionStorage.setItem('ineqName', JSON.stringify(this.ineqName));
                    }
                    this.selectedIneq = currentIneqName;
                  }

                }

              };
              eventSource.onerror = (error) => {
                console.error('EventSource failed:', error);
                this.submitLoading = false;
                this.dialogTitle = '生成过程中出现错误';
                eventSource.close();
                this.okLoading = false;
              };
            }).catch(error => {
              // 请求失败，处理错误
              console.error('请求失败:', error);
              // 可以根据错误类型提示用户或采取其他措施
            });
          } else {
            console.log('error submit!!');
            return false;
          }
        });
      },

      handleClose(action) {
        if (this.progress >= 100 || action === 'confirm') {
          // this.fetchData();
          this.resetForm('form');
          this.dialogVisible = false;
          eventSource.close();
        } else {
          this.$confirm('此操作将停止不等式生成, 是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            // 处理确认停止后的逻辑
            if (this.progress < 100) {

              this.$message({
                type: 'success',
                message: '成功取消!'
              });
              this.shutGenInequ();
              this.dialogVisible = false;
              // 重置状态
              this.submitLoading = false;
              eventSource.close(); // 关闭 EventSource

            } else {
              this.$message({
                type: 'error',
                message: '已完成生成!'
              });
            }
          }).catch(() => {

          });
        }
      },
      shutGenInequ() {
        // 使用 Axios 发起 POST 请求
        axios.get('http://127.0.0.1:8000/1/exterminate')
          .then(response => {
            // 请求成功，处理响应数据
            console.log('请求成功1:', response.data);
            // 根据需要处理response.data，比如更新状态、显示消息等
          })
          .catch(error => {
            // 请求失败，处理错误
            console.error('请求失败1:', error);
            // 可以根据错误类型提示用户或采取其他措施
          });
      },
      resetForm(formName) {
        this.$refs[formName].resetFields();
      },

      displayKeyTable() {
        if (isNaN(this.selectedKeyEIndex) || isNaN(this.selectedKeySIndex)) {
          this.$message({
            message: '选择列数不合法',
            type: 'warning'
          });
          return;
        }
        this.drawKeyVisible = true;
        this.generateKeyTable();

      },
      generateKeyTable() {
        this.keyTableEColumns = [];
        this.keyTableSColumns = [];
        this.filteredKeyETableData = [];
        this.filteredKeySTableData = [];

        const selectedEColumns = parseInt(this.selectedKeyEIndex);
        const selectedSColumns = parseInt(this.selectedKeySIndex);
        let startEIndex = selectedEColumns - 5;
        let endEIndex = selectedEColumns + 4;
        let startSIndex = selectedSColumns - 5;
        let endSIndex = selectedSColumns + 4;
        if (startEIndex < 0) {
          endEIndex = 9;
          startEIndex = 0;
        } else if (endEIndex >= 256) {
          endEIndex = 256 - 1;
          startEIndex = endEIndex - 9;
        }
        if (startSIndex < 0) {
          endSIndex = 9;
          startSIndex = 0;
        } else if (endSIndex >= this.version) {
          endSIndex = this.version - 1;
          startSIndex = endSIndex - 9;
        }
        const rowEData = {};
        const rowSData = {};
        for (let i = startEIndex; i <= endEIndex; i++) {
          this.keyTableEColumns.push({ label: `e[${i}]`, prop: `e${i}` })
          rowEData['e' + (i)] = this.keyFileContent[i];
        }
        for (let i = startSIndex; i <= endSIndex; i++) {
          this.keyTableSColumns.push({ label: `s[${i}]`, prop: `s${i}` })
          rowSData['s' + (i)] = this.keyFileContent[256 + i];
        }
        this.filteredKeyETableData.push(rowEData);
        this.filteredKeySTableData.push(rowSData);

      },
      displayCoeffTable() {
        if (isNaN(this.selectedInequIndex) && isNaN(this.selectedCoeffIndex)) {
          this.$message({
            message: '选择的不等式不合法',
            type: 'warning'
          });
          return;
        }
        this.coeffTableLoading = true;
        this.drawCoeffVisible = true;
        this.generateCoeffTable();

      },
      generateCoeffTable() {
        // console.log(this.selectedInequIndex)
        // console.log(this.selectedCoeffIndex)
        this.coeffTableColumns = [];
        this.filteredCoeffTableData = [];

        const inequIndex = parseInt(this.selectedInequIndex);

        const coeffIndex = parseInt(this.selectedCoeffIndex);

        let startInequIndex = inequIndex - 2;
        let endInequIndex = inequIndex + 2;
        if (startInequIndex < 0) {
          endInequIndex = 5;
          startInequIndex = 1;
        } else if (endInequIndex >= this.inequCount) {
          endInequIndex = this.inequCount;
          startInequIndex = endInequIndex - 4;
        }
        // console.log(startInequIndex, endInequIndex)


        let startCoeffIndex = coeffIndex - 4;
        let endCoeffIndex = coeffIndex + 5;
        if (startCoeffIndex < 0) {
          endCoeffIndex = 9;
          startCoeffIndex = 0;
        } else if (endCoeffIndex >= 256 + this.version) {
          endCoeffIndex = 256 + this.version - 1;
          startCoeffIndex = endCoeffIndex - 9;
        }
        // console.log(startCoeffIndex, endCoeffIndex)
        for (let i = startCoeffIndex; i <= endCoeffIndex; i++) {
          this.coeffTableColumns.push({ label: `A[${i}]`, prop: `A${i}` })
        }
        axios.post('http://127.0.0.1:8000/1/getInequ', {
          name: this.selectedIneq + '.txt',
          startIndex: startInequIndex - 1,
          endIndex: endInequIndex
        }, {
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
          }
        }).then(response1 => {
          this.coeffFileContent = response1.data.data;

          axios.post('http://127.0.0.1:8000/1/getInequ', {
            name: this.selectedIneq + '_lvu.txt',
            startIndex: startInequIndex - 1,
            endIndex: endInequIndex
          }, {
            headers: {
              'Content-Type': 'application/x-www-form-urlencoded'
            }
          }).then(response2 => {
            this.lvuFileContent = response2.data.data;

            for (let i = startInequIndex; i <= endInequIndex; i++) {
              const rowData = {
                No: i,
                lowerbound: this.lvuFileContent[(i - startInequIndex).toString()][0],
                upperbound: this.lvuFileContent[(i - startInequIndex).toString()][1],
              };
              // 合并系数数据，避免多次 split
              const line1 = this.coeffFileContent[(i - startInequIndex).toString()];

              for (let j = startCoeffIndex; j <= endCoeffIndex; j++) {
                rowData[`A${j}`] = line1[j];
              }
              this.filteredCoeffTableData.push(rowData);
              // console.log(rowData)
            }
            this.coeffTableLoading = false;


          }).catch(error => {
            // 请求失败，处理错误
            console.error('Second request failed:', error);
          });

        }).catch(error => {
          // 请求失败，处理错误
          console.error('First request failed:', error);
        });
      },
      fetchKeyData() {
        axios.post('http://127.0.0.1:8000/1/getInequ', {
          name: this.selectedIneq + '_es.txt',
          startIndex: 0,
          endIndex: 0

        }, {
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
          }
        }).then(response => {
          this.keyFileContent = response.data.data;

        }).catch(error => {
          // 请求失败，处理错误
          console.error('请求失败:', error);
          // 可以根据错误类型提示用户或采取其他措施
        });
      },
    },

  };
</script>

<style scoped>

  .clearfix:before,
  .clearfix:after {
    display: table;
    content: "";
  }

  .clearfix:after {
    clear: both
  }
</style>